<template>
    <div class="number-matcher">
        <div class="input-section">
            <!-- 前区号码选择 - 根据是否允许重复显示不同的选择方式 -->
            <div class="number-selector">
                <label>
                    前区号码 ({{ config.front.min }}-{{ config.front.max }},
                    {{ config.front.allowDuplicates ? `选${config.front.count}个，可重复` :
                        `至少选${config.front.minSelect}个，不可重复` }})
                </label>

                <!-- 允许重复时，每列单独占一行且左对齐 -->
                <div v-if="config.front.allowDuplicates" class="single-row-number-grid">
                    <div v-for="i in config.front.count" :key="`front-col-${i}`" class="number-row">
                        <p class="row-label">第{{ i }}位</p>
                        <div class="number-grid">
                            <button
                                v-for="num in Array.from({ length: config.front.max - config.front.min + 1 }, (_, idx) => idx + config.front.min)"
                                :key="`front-${i}-${num}`" class="number-btn"
                                :class="{ selected: selectedFront[i - 1] === num }"
                                @click="selectNumberInPosition(i - 1, num)" :disabled="isMatching">
                                {{ num }}
                            </button>
                        </div>
                    </div>
                </div>

                <!-- 不允许重复时，使用原来的选择方式 -->
                <div v-else class="number-grid">
                    <button
                        v-for="num in Array.from({ length: config.front.max - config.front.min + 1 }, (_, i) => i + config.front.min)"
                        :key="'front-' + num" class="number-btn" :class="{ selected: selectedFront.includes(num) }"
                        @click="toggleNumber('front', num)" :disabled="isMatching">
                        {{ num }}
                    </button>
                </div>

                <p class="selection-info">
                    已选择:
                    <span v-if="config.front.allowDuplicates">
                        {{selectedFront.filter(num => num !== null).length}}/{{ config.front.count }} 个
                    </span>
                    <span v-else>
                        {{ selectedFront.length }} 个
                    </span>
                    <span v-if="!isFrontSelectionValid" class="invalid-warning">
                        ({{ config.front.allowDuplicates ? `请选择${config.front.count}个号码` :
                            `至少选择${config.front.minSelect}个` }})
                    </span>
                </p>
            </div>

            <!-- 后区号码选择（仅当有后区时显示） -->
            <div v-if="hasBack" class="number-selector">
                <label>后区号码 ({{ config.back.min }}-{{ config.back.max }},
                    {{ config.back.allowDuplicates ? `选${config.back.count}个，可重复` : `至少选${config.back.minSelect}个，不可重复`
                    }})</label>

                <!-- 允许重复时，每列单独占一行且左对齐 -->
                <div v-if="config.back.allowDuplicates" class="single-row-number-grid">
                    <div v-for="i in config.back.count" :key="`back-col-${i}`" class="number-row">
                        <p class="row-label">第{{ i }}位</p>
                        <div class="number-grid">
                            <button
                                v-for="num in Array.from({ length: config.back.max - config.back.min + 1 }, (_, idx) => idx + config.back.min)"
                                :key="`back-${i}-${num}`" class="number-btn"
                                :class="{ selected: selectedBack[i - 1] === num }"
                                @click="selectNumberInPosition(i - 1, num, 'back')" :disabled="isMatching">
                                {{ num }}
                            </button>
                        </div>
                    </div>
                </div>

                <!-- 不允许重复时，使用原来的选择方式 -->
                <div v-else class="number-grid">
                    <button
                        v-for="num in Array.from({ length: config.back.max - config.back.min + 1 }, (_, i) => i + config.back.min)"
                        :key="'back-' + num" class="number-btn" :class="{ selected: selectedBack.includes(num) }"
                        @click="toggleNumber('back', num)" :disabled="isMatching">
                        {{ num }}
                    </button>
                </div>

                <p class="selection-info">
                    已选择:
                    <span v-if="config.back.allowDuplicates">
                        {{selectedBack.filter(num => num !== null).length}}/{{ config.back.count }} 个
                    </span>
                    <span v-else>
                        {{ selectedBack.length }} 个
                    </span>
                    <span v-if="!isBackSelectionValid" class="invalid-warning">
                        ({{ config.back.allowDuplicates ? `请选择${config.back.count}个号码` : `至少选择${config.back.minSelect}个`
                        }})
                    </span>
                </p>
            </div>

            <!-- 操作按钮 -->
            <div class="button-group">
                <button class="match-btn" @click="startMatching" :disabled="isMatching || !isSelectionComplete">
                    {{ isMatching ? '匹配中...' : '开始匹配' }}
                </button>
                <button class="cancel-btn" @click="cancelMatching" :disabled="!isMatching">
                    取消
                </button>
                <button class="clear-btn" @click="clearSelection" :disabled="isMatching">
                    清空选择
                </button>
            </div>

            <!-- 进度显示 -->
            <div v-if="isMatching" class="progress-container">
                <div class="progress-info">
                    已尝试: {{ attempts.toLocaleString() }} 次 | 进度: {{ progress }}%
                </div>
                <div class="progress-bar">
                    <div class="progress-fill" :style="{ width: progress + '%' }"></div>
                </div>
                <div class="time-info">
                    已用时: {{ elapsedTime }} 秒
                </div>
            </div>
        </div>

        <!-- 匹配结果 -->
        <div v-if="matchingResult" class="result-section">
            <h3>匹配结果</h3>
            <table>
                <tbody>
                    <tr>
                        <td>状态</td>
                        <td>{{ matchingResult.success ? '匹配成功' : '已达最大尝试次数' }}</td>
                    </tr>
                    <tr>
                        <td>总尝试次数</td>
                        <td>{{ matchingResult.attempts.toLocaleString() }}</td>
                    </tr>
                    <tr>
                        <td>耗时</td>
                        <td>{{ matchingResult.elapsedTime }} 秒</td>
                    </tr>
                    <tr>
                        <td>目标号码</td>
                        <td>
                            前区:
                            <template v-if="config.front.allowDuplicates">
                                <span class="number ball-front" v-for="(num, idx) in matchingResult.target.front"
                                    :key="'t-f-' + idx">{{ num }}</span>
                            </template>
                            <template v-else>
                                <span class="number ball-front" v-for="num in matchingResult.target.front"
                                    :key="'t-f' + num">{{ num }}</span>
                            </template>
                            <br>
                            <template v-if="hasBack">
                                后区:
                                <template v-if="config.back.allowDuplicates">
                                    <span class="number ball-back" v-for="(num, idx) in matchingResult.target.back"
                                        :key="'t-b-' + idx">{{ num }}</span>
                                </template>
                                <template v-else>
                                    <span class="number ball-back" v-for="num in matchingResult.target.back"
                                        :key="'t-b' + num">{{ num }}</span>
                                </template>
                            </template>
                        </td>
                    </tr>
                    <tr v-if="matchingResult.success">
                        <td>匹配号码</td>
                        <td>
                            前区:
                            <template v-if="config.front.allowDuplicates">
                                <span class="number ball-front" v-for="(num, idx) in matchingResult.numbers.front"
                                    :key="'f-' + idx">{{ num }}</span>
                            </template>
                            <template v-else>
                                <span class="number ball-front" v-for="num in matchingResult.numbers.front"
                                    :key="'f' + num">{{ num }}</span>
                            </template>
                            <br>
                            <template v-if="hasBack">
                                后区:
                                <template v-if="config.back.allowDuplicates">
                                    <span class="number ball-back" v-for="(num, idx) in matchingResult.numbers.back"
                                        :key="'b-' + idx">{{ num }}</span>
                                </template>
                                <template v-else>
                                    <span class="number ball-back" v-for="num in matchingResult.numbers.back"
                                        :key="'b' + num">{{ num }}</span>
                                </template>
                            </template>
                        </td>
                    </tr>
                </tbody>
            </table>
            <button class="reset-btn" @click="resetResult">重置</button>
        </div>
    </div>
</template>

<script setup>
import { ref, computed, onUnmounted, defineEmits } from 'vue'

// 定义事件
const emit = defineEmits(['match-success'])

// 接收父组件传递的彩票配置
const props = defineProps({
    config: {
        type: Object,
        required: true,
        default: () => ({
            hasBack: true,
            front: {
                count: 6,
                min: 1,
                max: 33,
                minSelect: 6,
                allowDuplicates: false // 是否允许重复号码
            },
            back: {
                count: 1,
                min: 1,
                max: 16,
                minSelect: 1,
                allowDuplicates: false // 是否允许重复号码
            }
        })
    }
})

// 计算属性：判断是否有后区
const hasBack = computed(() => {
    return props.config.hasBack !== undefined ? props.config.hasBack : true
})

// 状态管理
// 对于允许重复的号码，使用数组按位置存储；不允许重复的使用数组存储选中的值
const selectedFront = ref(
    props.config.front.allowDuplicates
        ? Array(props.config.front.count).fill(null)
        : []
)
const selectedBack = ref(
    hasBack.value && props.config.back?.allowDuplicates
        ? Array(props.config.back.count).fill(null)
        : []
)
const isMatching = ref(false)
const matchingResult = ref(null)
const attempts = ref(0)
const progress = ref(0)
const startTime = ref(0)
const elapsedTime = ref(0)
const timer = ref(null)
const MAX_ATTEMPTS = 50000000 // 五千万次封顶

// 计算属性：检查前后区选择是否满足要求
const isFrontSelectionValid = computed(() => {
    if (props.config.front.allowDuplicates) {
        // 允许重复时，检查是否选择了规定数量的号码
        return selectedFront.value.every(num => num !== null)
    } else {
        // 不允许重复时，检查是否达到最低选择数量
        return selectedFront.value.length >= props.config.front.minSelect
    }
})

const isBackSelectionValid = computed(() => {
    // 如果没有后区，默认后区选择有效
    if (!hasBack.value) return true

    if (props.config.back.allowDuplicates) {
        // 允许重复时，检查是否选择了规定数量的号码
        return selectedBack.value.every(num => num !== null)
    } else {
        // 不允许重复时，检查是否达到最低选择数量
        return selectedBack.value.length >= props.config.back.minSelect
    }
})

// 计算属性：检查是否满足所有选择条件
const isSelectionComplete = computed(() => {
    return isFrontSelectionValid.value && isBackSelectionValid.value
})

// 切换号码选择状态（适用于不允许重复的情况）
const toggleNumber = (type, num) => {
    if (type === 'front') {
        if (selectedFront.value.includes(num)) {
            selectedFront.value = selectedFront.value.filter(n => n !== num)
        } else {
            selectedFront.value = [...selectedFront.value, num].sort((a, b) => a - b)
        }
    } else if (hasBack.value) {
        if (selectedBack.value.includes(num)) {
            selectedBack.value = selectedBack.value.filter(n => n !== num)
        } else {
            selectedBack.value = [...selectedBack.value, num].sort((a, b) => a - b)
        }
    }
}

// 选择指定位置的号码（适用于允许重复的情况）
const selectNumberInPosition = (index, num, type = 'front') => {
    if (type === 'front') {
        const newFront = [...selectedFront.value]
        newFront[index] = num
        selectedFront.value = newFront
    } else if (hasBack.value) {
        const newBack = [...selectedBack.value]
        newBack[index] = num
        selectedBack.value = newBack
    }
}

// 清空选择
const clearSelection = () => {
    if (props.config.front.allowDuplicates) {
        selectedFront.value = Array(props.config.front.count).fill(null)
    } else {
        selectedFront.value = []
    }

    if (hasBack.value) {
        if (props.config.back?.allowDuplicates) {
            selectedBack.value = Array(props.config.back.count).fill(null)
        } else {
            selectedBack.value = []
        }
    }
}

// 生成随机号码（根据配置要求的数量和是否允许重复）
const generateRandomNumbers = () => {
    // 生成前区号码
    const front = []
    while (front.length < props.config.front.count) {
        const num = Math.floor(Math.random() * (props.config.front.max - props.config.front.min + 1)) + props.config.front.min
        // 如果不允许重复，确保号码不重复
        if (!props.config.front.allowDuplicates && front.includes(num)) {
            continue
        }
        front.push(num)
    }

    // 对于不允许重复的，排序显示
    if (!props.config.front.allowDuplicates) {
        front.sort((a, b) => a - b)
    }

    // 生成后区号码（如果有后区）
    const result = { front }
    if (hasBack.value) {
        const back = []
        while (back.length < props.config.back.count) {
            const num = Math.floor(Math.random() * (props.config.back.max - props.config.back.min + 1)) + props.config.back.min
            // 如果不允许重复，确保号码不重复
            if (!props.config.back.allowDuplicates && back.includes(num)) {
                continue
            }
            back.push(num)
        }

        // 对于不允许重复的，排序显示
        if (!props.config.back.allowDuplicates) {
            back.sort((a, b) => a - b)
        }
        result.back = back
    }

    return result
}

// 判断随机号码是否在选择范围内
const isNumberInSelection = (randomNums) => {
    // 检查前区号码是否符合选择
    if (props.config.front.allowDuplicates) {
        // 允许重复时，检查每个位置的号码是否匹配
        for (let i = 0; i < randomNums.front.length; i++) {
            if (randomNums.front[i] !== selectedFront.value[i]) {
                return false
            }
        }
    } else {
        // 不允许重复时，检查所有号码是否都在选择范围内
        for (const num of randomNums.front) {
            if (!selectedFront.value.includes(num)) {
                return false
            }
        }
    }

    // 如果有后区，检查后区号码是否符合选择
    if (hasBack.value) {
        if (props.config.back.allowDuplicates) {
            // 允许重复时，检查每个位置的号码是否匹配
            for (let i = 0; i < randomNums.back.length; i++) {
                if (randomNums.back[i] !== selectedBack.value[i]) {
                    return false
                }
            }
        } else {
            // 不允许重复时，检查所有号码是否都在选择范围内
            for (const num of randomNums.back) {
                if (!selectedBack.value.includes(num)) {
                    return false
                }
            }
        }
    }

    return true
}

// 匹配循环 - 严格控制在MAX_ATTEMPTS以内
const matchLoop = () => {
    return new Promise(resolve => {
        let iterations = 0
        const maxIterations = 1000000 // 每次循环执行的次数
        const remainingAttempts = MAX_ATTEMPTS - attempts.value
        const safeIterations = Math.min(maxIterations, remainingAttempts)

        const loop = () => {
            // 检查是否已达到最大尝试次数
            if (attempts.value >= MAX_ATTEMPTS) {
                resolve({ matched: null, completed: true })
                return
            }

            iterations++
            attempts.value++
            const current = generateRandomNumbers()

            // 更新进度
            progress.value = Math.min(Math.round((attempts.value / MAX_ATTEMPTS) * 100), 100)

            // 检查是否匹配成功
            if (isNumberInSelection(current)) {
                resolve({ matched: current, completed: true })
                return
            }

            // 继续循环或结束当前批次
            if (iterations < safeIterations && isMatching.value) {
                setImmediate(loop)
            } else {
                // 如果达到最大尝试次数，标记为完成
                const isComplete = attempts.value >= MAX_ATTEMPTS
                resolve({ matched: null, completed: isComplete })
            }
        }

        loop()
    })
}

// 目标号码范围
let targetRanges = null

// 更新 elapsedTime 的定时器
const updateElapsedTime = () => {
    timer.value = setInterval(() => {
        if (startTime.value) {
            elapsedTime.value = ((Date.now() - startTime.value) / 1000).toFixed(1)
        }
    }, 100)
}

// 开始匹配
const startMatching = async () => {
    // 验证输入
    if (!isSelectionComplete.value) return

    // 准备目标号码范围
    targetRanges = {
        front: [...selectedFront.value]
    }
    // 如果有后区，添加后区目标范围
    if (hasBack.value) {
        targetRanges.back = [...selectedBack.value]
    }

    // 初始化状态
    isMatching.value = true
    matchingResult.value = null
    attempts.value = 0
    progress.value = 0
    startTime.value = Date.now()
    elapsedTime.value = '0.0'
    updateElapsedTime()

    try {
        let matched = null
        let result

        // 循环直到匹配成功、达到最大次数或用户取消
        do {
            result = await matchLoop()
            if (result.matched) {
                matched = result.matched
            }
        } while (!result.completed && isMatching.value)

        // 计算总耗时
        const totalTime = ((Date.now() - startTime.value) / 1000).toFixed(1)

        // 设置匹配结果
        matchingResult.value = {
            success: !!matched,
            numbers: matched,
            target: targetRanges,
            attempts: attempts.value,
            elapsedTime: totalTime
        }

        // 触发成功事件
        if (matched) {
            emit('match-success', matchingResult.value)
        }
    } catch (error) {
        console.error('匹配出错:', error)
        alert('匹配过程出错，请重试')
    } finally {
        isMatching.value = false
        clearInterval(timer.value)
    }
}

// 取消匹配
const cancelMatching = () => {
    isMatching.value = false
    clearInterval(timer.value)
}

// 重置结果
const resetResult = () => {
    matchingResult.value = null
    clearSelection()
    attempts.value = 0
    progress.value = 0
}

// 清理定时器
onUnmounted(() => {
    clearInterval(timer.value)
})
</script>

<style scoped>
.number-matcher {
    max-width: 1200px;
    margin: 0 auto;
    padding: 1rem;
}

.number-selector {
    margin-bottom: 2rem;
}

.number-selector label {
    display: block;
    margin-bottom: 0.8rem;
    color: #666;
    font-weight: 500;
}

/* 允许重复时的样式 - 每列单独占一行且左对齐 */
.single-row-number-grid {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    /* 行与行之间的间距 */
}

.number-row {
    display: flex;
    align-items: center;
    gap: 1rem;
    width: 100%;
    justify-content: flex-start;
    /* 左对齐 */
}

.row-label {
    width: 60px;
    /* 固定标签宽度，确保对齐 */
    font-weight: 500;
    color: #666;
    margin: 0;
    text-align: left;
    /* 标签文字左对齐 */
}

.number-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0;
    padding: 0;
    justify-content: flex-start;
    /* 号码按钮左对齐排列 */
    flex: 1;
    /* 占据剩余空间 */
}

.number-btn {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: 2px solid #ddd;
    background-color: white;
    cursor: pointer;
    font-weight: bold;
    transition: all 0.2s;
}

.number-btn.selected {
    background-color: #42b983;
    color: white;
    border-color: #42b983;
}

.number-btn:hover:not(.selected) {
    border-color: #42b983;
}

.selection-info {
    color: #666;
    margin: 0.5rem 0 0 0;
    font-size: 0.9rem;
    text-align: left;
    /* 选择信息左对齐 */
    padding-left: 60px;
    /* 与号码行标签对齐 */
}

.invalid-warning {
    color: #ff4444;
    margin-left: 0.5rem;
    font-size: 0.8rem;
}

.button-group {
    display: flex;
    gap: 1rem;
    justify-content: flex-start;
    /* 按钮组左对齐 */
    margin-bottom: 1.5rem;
    flex-wrap: wrap;
    padding-left: 0;
    /* 移除默认内边距 */
}

.match-btn {
    padding: 0.8rem 2rem;
    background-color: #42b983;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 1rem;
    transition: background-color 0.3s;
}

.match-btn:disabled {
    background-color: #ccc;
    cursor: not-allowed;
}

.cancel-btn {
    padding: 0.8rem 2rem;
    background-color: #ff4444;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 1rem;
    transition: background-color 0.3s;
}

.cancel-btn:disabled {
    background-color: #ffaaaa;
    cursor: not-allowed;
}

.clear-btn {
    padding: 0.8rem 2rem;
    background-color: #666;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 1rem;
    transition: background-color 0.3s;
}

.clear-btn:disabled {
    background-color: #999;
    cursor: not-allowed;
}

.progress-container {
    margin: 1rem 0;
    text-align: left;
    /* 进度条区域左对齐 */
}

.progress-info {
    color: #666;
    margin-bottom: 0.5rem;
}

.progress-bar {
    height: 10px;
    background-color: #eee;
    border-radius: 5px;
    overflow: hidden;
    margin-bottom: 0.5rem;
}

.progress-fill {
    height: 100%;
    background-color: #42b983;
    transition: width 0.1s;
}

.time-info {
    color: #666;
    font-size: 0.9rem;
}

.result-section {
    margin-top: 2rem;
    padding: 1.5rem;
    border: 1px solid #42b983;
    border-radius: 4px;
    text-align: left;
    /* 结果区域左对齐 */
}

.result-section h3 {
    color: #333;
    margin-top: 0;
    margin-bottom: 1rem;
}

.result-section table {
    width: 100%;
    border-collapse: collapse;
}

.result-section td {
    padding: 0.8rem;
    border-bottom: 1px solid #eee;
}

.result-section td:first-child {
    font-weight: bold;
    width: 30%;
}

.number {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    color: white;
    font-size: 0.8rem;
    margin-right: 5px;
    margin-bottom: 5px;
}

.ball-front {
    background-color: #42b983;
}

.ball-back {
    background-color: #3498db;
}

.reset-btn {
    margin-top: 1rem;
    padding: 0.5rem 1rem;
    background-color: #666;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    transition: background-color 0.3s;
}

.reset-btn:hover {
    background-color: #555;
}

/* 响应式调整 */
@media (max-width: 768px) {
    .number-row {
        flex-direction: column;
        align-items: flex-start;
    }

    .row-label {
        margin-bottom: 0.5rem;
    }

    .selection-info {
        padding-left: 0;
    }
}
</style>
